function defineType(s) {
    return s
}
defineType.prototype = new String()
const str = 'string'
const num = 123
const b = true
const nu = null
const undef = undefined
const obj = { num: 1, str: 'string' }
const arr = [1, 'string', true]
const date = new Date()
const reg = new RegExp(/[0,1]/)
const sym = Symbol('symbol')
const bigNum = BigInt(15560049120)
const fun = (param) => {
    return param || 'function'
}
const define = new defineType('1')


const objArr = [str, num, b, nu, undef, obj, arr, date, reg, sym, bigNum, fun, define]
const typeArr = []
const typeofArr = []
const instanceArr = []
const callArr = []
const constructorArr = []

/**
 * 获取元素类型
 * @param {*} item 
 * @returns 
 */
const getType = (item) => {
    const type = typeof item
    if(type !== 'object') return type[0].toUpperCase() + type.substring(1)
    else {
        // return Object.prototype.toString.call(item).split(' ')[1].split(']')[0]
        return Object.prototype.toString.call(item).split(/(\s|\[|\])/)[4]
    } 
}

/**
 * 根据 instanceof 获取类型
 * @param {*} item 
 * @returns 
 */
const getTypeByInstance = (item) => {
    const typeArr = [Array, Date, RegExp, Function, Object]
    for (let i = 0; i < typeArr.length; i++) {
        const it = typeArr[i];
        if (item instanceof it) return it.name
    }
    return ''
    // if (item instanceof Array) return 'Array'
    // else if (item instanceof Date) return 'Date'
    // else if (item instanceof RegExp) return 'RegExp'
    // else if (item instanceof Function) return 'Function'
    // else if (item instanceof Object) return 'Object'
    // else return ''
}

/**
 * 使用 Object 来获取当前元素的类型
 * @param {*} item 
 * @returns 
 */
const getTypeByProto = (item) => {
    return Object.prototype.toString.call(item)
}

const getTypeByConstructor = (item) => {
    // return (item)?.constructor.toString().split(' ')[1].split(/[(,)]/)[0] || ''
    return (item)?.constructor || ''
}
objArr.forEach(item => {
    const typeItem = getType(item)
    const typeofItem = (typeof item).padEnd(10, ' ')
    const instanceItem = getTypeByInstance(item).padEnd(10, ' ')
    const callItem = getTypeByProto(item).padEnd(18, ' ')
    const constructorItem = getTypeByConstructor(item)

    typeArr.push(typeItem)
    typeofArr.push(typeofItem)
    instanceArr.push(instanceItem)
    callArr.push(callItem)
    constructorArr.push(constructorItem)
})

objArr.forEach((_, index) => {
    console.log(typeArr[index], typeofArr[index], instanceArr[index], callArr[index], constructorArr[index])
})
// console.log(Array + '');